package com.szis.auth.common.utils;

public class CustomSnowflakeIdGenerator {

    // 各部分占用位数
    private final long nodeIdBits = 12L;
    private final long serviceIdBits = 10L;
    private final long sequenceBits = 12L;
    private final long timestampBits = 30L;

    // 最大值限制
    private final long maxServiceId = ~(-1L << serviceIdBits); // 1023
    private final long maxNodeId = ~(-1L << nodeIdBits);       // 4095
    private final long maxSequence = ~(-1L << sequenceBits);   // 4095

    // 偏移量
    private final long sequenceShift = serviceIdBits + nodeIdBits;
    private final long nodeIdShift = serviceIdBits;
    private final long timestampShift = serviceIdBits + nodeIdBits + sequenceBits;

    // 起始时间戳（如：2025-01-01）
    private final long nodeId;
    private final long serviceId;

    private long lastTimestamp = -1L;
    private long sequence = 0L;

    /**
     * 构造函数
     * @param serviceId 服务ID（0 ~ 1023）
     * @param nodeId 节点ID（0 ~ 4095）
     */
    public CustomSnowflakeIdGenerator(long serviceId, long nodeId) {
        if (serviceId < 0 || serviceId > maxServiceId) {
            throw new IllegalArgumentException("服务ID超出范围");
        }
        if (nodeId < 0 || nodeId > maxNodeId) {
            throw new IllegalArgumentException("节点ID超出范围");
        }
        this.serviceId = serviceId;
        this.nodeId = nodeId;
    }

    /**
     * 获取下一个ID
     */
    public synchronized long nextId() {
        long timestamp = System.currentTimeMillis();

        if (timestamp < lastTimestamp) {
            throw new RuntimeException("时钟回拨");
        }

        if (timestamp == lastTimestamp) {
            sequence = (sequence + 1) & maxSequence;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0;
        }

        lastTimestamp = timestamp;

        return (timestamp << timestampShift)
                | (serviceId << serviceIdBits)
                | (nodeId << nodeIdShift)
                | sequence;
    }

    /**
     * 等待下一毫秒
     */
    private long tilNextMillis(long lastTimestamp) {
        long timestamp = System.currentTimeMillis();
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis();
        }
        return timestamp;
    }

    /**
     * 解析 ID 并打印各部分
     */
    public static void parseId(long id) {
        long serviceId = (id >> (42)) & 0b1111111111L; // 10位
        long nodeId = (id >> 12) & 0b111111111111L;     // 12位
        long sequence = id & 0b111111111111L;          // 12位
        long timestamp = (id >> 22);                    // 41位

        System.out.println("时间戳: " + timestamp);
        System.out.println("服务ID: " + serviceId);
        System.out.println("节点ID: " + nodeId);
        System.out.println("序列号: " + sequence);
    }

    // 示例使用
    public static void main(String[] args) {
        // 示例：服务ID=10，节点ID=5
        CustomSnowflakeIdGenerator idGen = new CustomSnowflakeIdGenerator(10, 5);

        for (int i = 0; i < 10; i++) {
            long id = idGen.nextId();
            System.out.println("生成ID: " + id);
            parseId(id);
        }
    }
}
